package games;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Random;

public class SnakeGame extends JPanel implements ActionListener {
    private static final int WIDTH = 600;
    private static final int HEIGHT = 600;
    private static final int DOT_SIZE = 15;
    private static final int ALL_DOTS = (WIDTH * HEIGHT) / (DOT_SIZE * DOT_SIZE);
    private static final int RAND_POS = 30;

    // 难度级别
    private static final int EASY = 150;   // 简单模式，蛇移动较慢
    private static final int MEDIUM = 100; // 中等模式
    private static final int HARD = 50;    // 困难模式，蛇移动较快

    private int[] x = new int[ALL_DOTS];
    private int[] y = new int[ALL_DOTS];
    private int dots;
    private int appleX;
    private int appleY;
    private int direction = 1; // 1=right, 2=left, 3=up, 4=down
    private boolean inGame = true;
    private Timer timer;
    private int score = 0;     // 分数
    private int difficulty = EASY; // 默认难度
    private int appleType;     // 苹果类型

    // 苹果类型定义
    private static final int NORMAL_APPLE = 0;  // 普通苹果
    private static final int SPEED_UP_APPLE = 1; // 加速苹果
    private static final int SLOW_DOWN_APPLE = 2; // 减速苹果
    private static final int LONGER_APPLE = 3;    // 长蛇苹果

    private JComboBox difficultyComboBox;

    public SnakeGame() {
        initGame();
        setPreferredSize(new Dimension(WIDTH, HEIGHT));
        setBackground(Color.BLACK);
        setFocusable(true);
        timer = new Timer(difficulty, this);
        timer.start();
        addKeyListener(new DirectionKeyListener());

        // 创建难度级别选择框
        difficultyComboBox = new JComboBox(new String[]{"简单", "中等", "困难"});
        difficultyComboBox.addActionListener(e -> {
            String selectedDifficulty = (String) difficultyComboBox.getSelectedItem();
            setDifficulty(selectedDifficulty);
            restartGame();
        });
        add(difficultyComboBox, BorderLayout.NORTH);
    }

    private void setDifficulty(String selectedDifficulty) {
        switch (selectedDifficulty) {
            case "简单":
                difficulty = EASY;
                break;
            case "中等":
                difficulty = MEDIUM;
                break;
            case "困难":
                difficulty = HARD;
                break;
        }
        timer.setDelay(difficulty);
    }

    private void initGame() {
        dots = 3;
        for (int i = 0; i < dots; i++) {
            x[i] = 45 - i * DOT_SIZE;
            y[i] = 45;
        }
        createApple();
        score = 0;
        inGame = true;
    }

    private void createApple() {
        Random random = new Random();
        appleX = random.nextInt(RAND_POS) * DOT_SIZE;
        appleY = random.nextInt(RAND_POS) * DOT_SIZE;
        // 随机生成苹果类型
        appleType = random.nextInt(4); // 0-3之间的随机数
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (inGame) {
            // 绘制苹果，不同类型的苹果颜色不同
            switch (appleType) {
                case NORMAL_APPLE:
                    g.setColor(Color.RED); // 普通苹果
                    break;
                case SPEED_UP_APPLE:
                    g.setColor(Color.MAGENTA); // 加速苹果
                    break;
                case SLOW_DOWN_APPLE:
                    g.setColor(Color.CYAN); // 减速苹果
                    break;
                case LONGER_APPLE:
                    g.setColor(Color.ORANGE); // 长蛇苹果
                    break;
            }
            g.fillOval(appleX, appleY, DOT_SIZE, DOT_SIZE);

            // 绘制蛇
            g.setColor(Color.GREEN);
            for (int i = 0; i < dots; i++) {
                g.fillRect(x[i], y[i], DOT_SIZE, DOT_SIZE);
            }

            // 绘制分数
            g.setColor(Color.WHITE);
            g.setFont(new Font("Arial", Font.BOLD, 20));
            g.drawString("分数: " + score, WIDTH - 100, 30);
        } else {
            gameOver(g);
        }
    }

    private void gameOver(Graphics g) {
        g.setColor(Color.RED);
        g.setFont(new Font("Arial", Font.BOLD, 50));
        FontMetrics metrics = getFontMetrics(g.getFont());
        g.drawString("Game Over", (WIDTH - metrics.stringWidth("Game Over")) / 2, HEIGHT / 2);

        // 绘制最终分数
        g.setFont(new Font("Arial", Font.BOLD, 30));
        metrics = getFontMetrics(g.getFont());
        g.drawString("最终分数: " + score, (WIDTH - metrics.stringWidth("最终分数: " + score)) / 2, HEIGHT / 2 + 50);

        // 绘制重新开始提示
        g.setFont(new Font("Arial", Font.BOLD, 20));
        metrics = getFontMetrics(g.getFont());
        g.drawString("按 R 键重新开始", (WIDTH - metrics.stringWidth("按 R 键重新开始")) / 2, HEIGHT / 2 + 100);
    }

    private void move() {
        for (int i = dots; i > 0; i--) {
            x[i] = x[i - 1];
            y[i] = y[i - 1];
        }

        if (direction == 1) {
            x[0] += DOT_SIZE;
        }
        if (direction == 2) {
            x[0] -= DOT_SIZE;
        }
        if (direction == 3) {
            y[0] -= DOT_SIZE;
        }
        if (direction == 4) {
            y[0] += DOT_SIZE;
        }

        checkCollision();
        checkApple();
    }

    private void checkCollision() {
        for (int i = dots; i > 0; i--) {
            if ((i > 4) && (x[0] == x[i]) && (y[0] == y[i])) {
                inGame = false;
            }
        }

        if (x[0] > WIDTH) {
            inGame = false;
        }
        if (x[0] < 0) {
            inGame = false;
        }
        if (y[0] > HEIGHT) {
            inGame = false;
        }
        if (y[0] < 0) {
            inGame = false;
        }
    }

    private void checkApple() {
        if ((x[0] == appleX) && (y[0] == appleY)) {
            // 根据苹果类型处理不同的效果
            switch (appleType) {
                case NORMAL_APPLE:
                    // 普通苹果：增加长度，增加分数
                    dots++;
                    score += 10;
                    break;
                case SPEED_UP_APPLE:
                    // 加速苹果：增加长度，增加分数，加速蛇
                    dots++;
                    score += 20;
                    if (timer.getDelay() > 20) {
                        timer.setDelay(timer.getDelay() - 20);
                    }
                    break;
                case SLOW_DOWN_APPLE:
                    // 减速苹果：增加长度，增加分数，减速蛇
                    dots++;
                    score += 5;
                    timer.setDelay(timer.getDelay() + 20);
                    break;
                case LONGER_APPLE:
                    // 长蛇苹果：大幅增加长度，增加分数
                    dots += 3;
                    score += 30;
                    break;
            }
            createApple();
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (inGame) {
            move();
        }
        repaint();
    }

    private class DirectionKeyListener extends KeyAdapter {
        @Override
        public void keyPressed(KeyEvent e) {
            int key = e.getKeyCode();
            if ((key == KeyEvent.VK_LEFT) && (direction != 1)) {
                direction = 2;
            }
            if ((key == KeyEvent.VK_RIGHT) && (direction != 2)) {
                direction = 1;
            }
            if ((key == KeyEvent.VK_UP) && (direction != 4)) {
                direction = 3;
            }
            if ((key == KeyEvent.VK_DOWN) && (direction != 3)) {
                direction = 4;
            }
            if (key == KeyEvent.VK_R && !inGame) {
                restartGame();
            }
        }
    }

    private void restartGame() {
        initGame();
        timer.setDelay(difficulty);
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("Snake Game");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new SnakeGame());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}
